package com.shudes.eval;

import java.math.*;
import java.util.*;

import com.shudes.game.*;

public class EquityResult extends EquityInput {

	protected Map<HoleCards, Counts> counts;  	
	
	EquityResult() {
		counts = new HashMap<HoleCards, Counts>();
	}
	
	EquityResult(EquityInput input) { 
		super(input.getHero(), input.getBoard(), input.getVillians(), input.getDeadCards());
		counts = new HashMap<HoleCards, Counts>();
	}

	public Counts getCounts(HoleCards hc) { 
		return counts.get(hc); 
	}
	
	Map<HoleCards, Counts> getCountsMap() { 
		return counts; 
	}
	
	void addObservation(EquityObservation ob) {
		Counts c; 
		GameResult gs; 
		
		System.out.println("adding: " + ob.getObservationMap()); 
		
		for(HoleCards hc : ob.getObservationMap().keySet()) {
			c = counts.get(hc); 
			if(c==null) { 
				c = new Counts(); 
			}
			
			gs = ob.getObservationMap().get(hc); 
			c.incrementCount(gs);
			if(GameResult.TIE.equals(gs)) { 
				c.addTieEquity(ob.getTieCount()); 
			}
			counts.put(hc, c); 
		}
	}
	
	public String toString() { 
		return counts.toString(); 
	}
	
	Set<Card> getKnownCards() { 
		Set<Card> knowns = new HashSet<Card>();
		
		if(this.board!=null && this.board.size()>0)
			knowns.addAll(board.getCards());
		
		if(this.hero!=null) 
			knowns.addAll(hero.getCards()); 
		
		if(this.villians!=null) { 
			for(HoleCards c : villians) { 
				knowns.addAll(c.getCards()); 
			}
		}
		
		return knowns; 				
	}
		
	public static class Counts { 
		Map<GameResult, Integer> map;
		BigDecimal tieEquity;

		Counts() { 
			map = new HashMap<GameResult, Integer>();
			map.put(GameResult.WIN, 0); 
			map.put(GameResult.LOSS, 0); 
			map.put(GameResult.TIE, 0);
			tieEquity = new BigDecimal("0"); 
		}
		
		public Integer getTotal() { 
			return getWin() + getLoss() + getTie(); 			
		}
		
		public Integer getWin() { 
			return getCount(GameResult.WIN); 
		}
		
		public Integer getLoss() { 
			return getCount(GameResult.LOSS); 
		}
		
		public Integer getTie() { 
			return getCount(GameResult.TIE); 
		}
		
		public Integer getCount(GameResult gs ) { 
			return map.get(gs); 
		}
		
		public void addTieEquity(int numberOfPlayers) { 
			BigDecimal f = new BigDecimal("1"); 
			f = f.divide(new BigDecimal(""+numberOfPlayers));
			tieEquity.add(f); 
		}
		
		public void incrementCount(GameResult gr) { 
			map.put(gr, map.get(gr)+1);
		}
				
		public BigDecimal getEquity() { 

			BigDecimal n;
			Integer total; 
			
			total = getWin() + getLoss() + getTie(); 
			
			n =new BigDecimal(""+getWin());
			n = n.divide(new BigDecimal(total)); 
			n = n.add(tieEquity.divide(new BigDecimal("" + getTie()))); 

			return n; 			
		}
		
		public String toString() { 
			return map.toString(); 
		}
	}
}
